package com.hhd.flow.engine.cmd.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.hhd.flow.engine.utils.CommonUtils;
import com.hhd.flow.engine.utils.FlowUtils;
import com.hhd.flow.engine.vo.ApproveType;
import com.hhd.flow.engine.vo.CommentType;
import com.hhd.flow.engine.vo.FlowModel;
import com.hhd.flow.engine.vo.FlowUser;
import com.hhd.flow.entity.*;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.SuperBuilder;
import org.springframework.beans.BeanUtils;

import java.util.List;

@Setter
@Getter
@SuperBuilder(toBuilder = true)
public class ToFormByAdminCommand extends BaseCommand<Void> {
    private JSONObject model; //业务单据的数据
    private String comment; //用户的评论
    private String userSign; //用户的手签
    private String attachmentIds; //附件列表
    private ApproveType approveType;//用户的处理类型
    private String commentInfo; //评论其他信息(用来给前端做特殊展示, json格式)
    private String processInstanceId;
    private String formId;

    //下面是运转过程中产生的数据
    private FlowComment flowComment;
    private FlowProcessInstance processInstance;
    private FlowProcessInstanceHistory flowProcessInstanceHistory;
    private FlowModel flowModel;

    @Override
    public Void execute() {
        loadData();

        createComment();

        publishFlowUserTaskBeforeToFormEvent();

        doToFormUserTask();

        publishFlowUserTaskAfterToFormEvent();

//        forFlowUserDone(flowUserTask.getFormId());
        clearFlowUserDone(formId);
        return null;
    }

    private void publishFlowUserTaskAfterToFormEvent() {
        ToFormCommand toFormCommand = ToFormCommand.builder().build();
        try {
            BeanUtil.copyProperties(this, toFormCommand);
        } catch (Exception e) {
        }
        publishFlowUserTaskAfterToFormEvent(toFormCommand);
    }

    private void doToFormUserTask() {
        savePath();
        getEngine().getFlowTaskService().lambdaUpdate()
                .eq(FlowTask::getProcessInstanceId, processInstanceId)
                .remove();

        getEngine().getFlowUserTaskService().lambdaUpdate()
                .eq(FlowUserTask::getProcessInstanceId, processInstanceId)
                .remove();

        getEngine().getFlowGatewayExecutionService().lambdaUpdate()
                .eq(FlowGatewayExecution::getProcessInstanceId, processInstanceId)
                .remove();

        removeProcessInstanceToHistory();
    }

    private void savePath() {
        FlowPath flowPath = loadFlowPathByProcessInstance(processInstance);
        List<FlowUserTask> list = getEngine().getFlowUserTaskService()
                .lambdaQuery()
                .eq(FlowUserTask::getProcessInstanceId, processInstanceId)
                .list();
        flowPath.setEndId("end");
        if (!CommonUtils.isEmpty(list)) {
            flowPath.setEndId(list.get(0).getTaskDefinitionId());
        }
        savePath(flowPath);
    }

    private void removeProcessInstanceToHistory() {
        processInstance = getEngine().getFlowProcessInstanceService().getById(processInstanceId);
        getEngine().getFlowProcessInstanceService().removeById(processInstance.getId());
        flowProcessInstanceHistory = FlowUtils.createFlowProcessInstanceHistory(processInstance, CommentType.toForm, false);
        getEngine().getFlowProcessInstanceHistoryService().save(flowProcessInstanceHistory);
        BeanUtils.copyProperties(flowProcessInstanceHistory, processInstance);
    }

    private void publishFlowUserTaskBeforeToFormEvent() {
        ToFormCommand toFormCommand = ToFormCommand.builder().build();
        try {
            BeanUtil.copyProperties(this, toFormCommand);
        } catch (Exception e) {
        }
        publishFlowUserTaskBeforeToFormEvent(toFormCommand);
    }

    private void createComment() {
        if (!CommonUtils.isEmpty(this.comment)) {
            FlowUser currentUser = getEngine().getCurrentUser();
            FlowUserTask flowUserTask = new FlowUserTask();
            flowUserTask.setUserId(currentUser.getId());
            flowUserTask.setUsername(currentUser.getUsername());
            flowUserTask.setTaskInstanceId("end");
            flowUserTask.setTaskDefinitionId("end");
            flowUserTask.setProcessInstanceId(processInstanceId);
            flowUserTask.setProcessDefinitionId(processInstance.getProcessDefinitionId());
            flowUserTask.setTaskName("回退");
            flowUserTask.setFormId(this.formId);

            flowComment = FlowUtils.createComment(flowUserTask, comment, userSign, attachmentIds, approveType, commentInfo);
            flowComment.setCommentType(CommentType.toForm.name());
            flowComment.setCommentTypeName(CommentType.toForm.getTitle());
            getEngine().getFlowCommentService().save(flowComment);
        }
    }

    private void loadData() {
        processInstance = getEngine().getFlowProcessInstanceService().getById(processInstanceId);
        CommonUtils.isEmptyThrow(processInstance, new RuntimeException("流程可能已经结束, 请刷新页面后重试"));
        flowModel = loadFlowModelByProcessInstanceId(processInstanceId);
    }
}
